package com.irdstudio.efp.esb.api.service.sed.credit;

import com.irdstudio.basic.framework.core.exception.BizException;
import com.irdstudio.basic.framework.core.util.DateUtility;
import com.irdstudio.basic.framework.core.util.TimeUtil;
import com.irdstudio.efp.cus.service.facade.CusIndivService;
import com.irdstudio.efp.esb.api.bean.sed.credit.req.ReqSedCreditQueryBean;
import com.irdstudio.efp.esb.api.common.sed.SedCreditQueryTypeEnum;
import com.irdstudio.efp.nls.service.facade.psd.NlsApplyApprovalInfoService;
import com.irdstudio.efp.nls.service.facade.psd.NlsCreditApprovalInfoService;
import com.irdstudio.efp.nls.service.facade.queue.NlsProcessBizService;
import com.irdstudio.efp.nls.service.facade.sx.NlsCreditInfoService;
import com.irdstudio.efp.nls.service.vo.psd.NlsCreditApprovalInfoVO;
import com.irdstudio.efp.nls.service.vo.queue.NlsProcessBizVO;
import com.irdstudio.efp.nls.service.vo.sx.NlsCreditInfoVO;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.apache.poi.ss.usermodel.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
* 普税贷产品对税e贷产品的此部分代码做了复用
* 说明：为了保证功能的复用性、提升开发的工作效率，对该代码进行了复用
* 评估是否会影响线上功能：否
* 评估时间：2020/5/25
* 处理方案：保留复用
*/
/**
 * 授信查询服务<br>
 * 
 * @author zhoucs1
 * @version 1.0
 * @since 2019年4月18日 下午5:46:29
 */
@Service("nlsSedCreditQueryService")
public class NlsSedCreditQueryService {
	
	// ZX30天查询结果-是
	private final String ZX_30DAYS_Y = "Y";
	// ZX30天查询结果-否
	private final String ZX_30DAYS_N = "N";
	// ZX30天天数
	private final String ZX_30DAYS = "30";
	// 授信申请状态-拒绝
	private final String APPRV_STATUS_03 = "03";
	// 征信插槽的状态-成功
	private final String SOLT_STATE_03 = "03";
	// 默认第一页
	private final String DEFAULT_PAGE_NO = "1";
	// 默认每页显示10条记录
	private final String DEFAULT_PAGE_SIZE = "10";
	// 数字正则表达式
	private final String NUM_RGX = "^[1-9]{1}[0-9]*$";
	

	/**
	 * 获取zx30Days的数据，30天内：1、跑过征信查询的插槽；2、30内授信有被拒绝过<br/>
	 * 
	 * @author zhoucs1
	 * @since 2019年4月18日 下午5:43:37
	 * @param reqSedCreditQueryBean
	 * @param nlsCreditInfoVOList
	 * @return String
	 * @throws Exception
	 */
	public String queryZx30DaysStatus(ReqSedCreditQueryBean reqSedCreditQueryBean) throws Exception {
		String cusId = reqSedCreditQueryBean.getCusId(); /* 客户号 */
		String certType = reqSedCreditQueryBean.getCertType(); /* 证件类型 */
		String certCode = reqSedCreditQueryBean.getCertCode(); /* 证件号码 */
		// 通过身份证信息去查询客户是否存在，不存在则说明没查过征信
		cusId = cusIndivService.getCusIdByCertCode(certType, certCode);
		if (cusId == null) {
			return ZX_30DAYS_N;
		}

		NlsProcessBizVO nlsProcessBizVO = new NlsProcessBizVO();
		nlsProcessBizVO.setCusId(cusId);
		//系统当前日期
		String nowDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
		List<NlsProcessBizVO> nlsProcessBizVOList = Optional
				.ofNullable(nlsProcessBizService.queryAllByCondition(nlsProcessBizVO)).orElseGet(ArrayList::new);
		for (NlsProcessBizVO innerNlsProcessBizVO : nlsProcessBizVOList) {
			if (SOLT_STATE_03.equals(innerNlsProcessBizVO.getSoltState8())
					&& TimeUtil.compareDates(nowDate, TimeUtil.addDay(innerNlsProcessBizVO.getCreateTime().substring(0,9), Integer.valueOf(ZX_30DAYS))) < 0) {// 1、30天内有查询过征信
				return ZX_30DAYS_Y;
			}
		}
		
		//查询当前身份证号下所有的授信记录用于征信30天的校验
		List<NlsCreditInfoVO> nlsCreditInfoVOList;
		NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
		nlsCreditInfoVO.setCertType(certType);
		nlsCreditInfoVO.setCertCode(certCode);
		nlsCreditInfoVOList = Optional.ofNullable(nlsCreditInfoService.queryAllByCondition(nlsCreditInfoVO)).orElseGet(ArrayList::new);
		for (NlsCreditInfoVO innerNlsCreditInfoVO : nlsCreditInfoVOList) { // 2、30内授信有被拒绝过
			if (APPRV_STATUS_03.equals(innerNlsCreditInfoVO.getApprvSts())
					&& TimeUtil.compareDates(nowDate, TimeUtil.addDay(innerNlsCreditInfoVO.getApplyDate().substring(0,9), Integer.valueOf(ZX_30DAYS))) < 0) {
				return ZX_30DAYS_Y;
			}
		}
		return ZX_30DAYS_N;
	}

	/**
	 * 处理授信查询结果<br/>
	 * 
	 * @author zhoucs1
	 * @since 2019年4月18日 下午5:44:55
	 * @param nlsCreditInfoVOList
	 * @param qryType
	 * @param pageNo
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
	public List<NlsCreditInfoVO> handleResultList(List<NlsCreditInfoVO> nlsCreditInfoVOList, String qryType,
                                                  String pageNo, String pageSize) throws Exception {
		int intPageNo = 0;
		int intPageSize = 0;
		if (!SedCreditQueryTypeEnum.QUERY_TYPE_01.getValue().equals(qryType)) {

			if (pageNo == null || "".equals(pageNo) || !pageNo.matches(NUM_RGX)) {
				pageNo = DEFAULT_PAGE_NO; // 没有传入页码的情况下查询第一页
			}
			if (pageSize == null || "".equals(pageSize) || !pageSize.matches(NUM_RGX)) {
				pageSize = DEFAULT_PAGE_SIZE; // 没有一页显示几行数据时，默认显示10条数据
			}
			intPageNo = Integer.valueOf(pageNo);
			intPageSize = Integer.valueOf(pageSize);
		} else {
			return nlsCreditInfoVOList;
		}
		List<NlsCreditInfoVO> newNlsCreditInfoVOList = new ArrayList<NlsCreditInfoVO>();
		int totalSize = nlsCreditInfoVOList.size();
		
		// 传入的页码数和记录数的乘积超过总记录数，直接返回数组为空
		if((long) intPageSize * (intPageNo - 1) >= (long) totalSize) {
			return newNlsCreditInfoVOList;
		}
		for (int i = intPageSize * (intPageNo - 1); i < totalSize && i < intPageSize * intPageNo; i++) {
			newNlsCreditInfoVOList.add(nlsCreditInfoVOList.get(i));
		}
		return newNlsCreditInfoVOList;
	}

	/**
	 * 处理查询参数<br/>
	 * 
	 * @author zhoucs1
	 * @since 2019年4月18日 下午5:45:45
	 * @param nlsCreditInfoVO
	 * @param qryType
	 * @param reqSedCreditQueryBean
	 * @return 
	 * @throws Exception
	 */
	public List<NlsCreditInfoVO> transferQueryParams(NlsCreditInfoVO nlsCreditInfoVO, String qryType,
                                                     ReqSedCreditQueryBean reqSedCreditQueryBean) throws Exception {
		String lmtApplySeq = reqSedCreditQueryBean.getLmtApplySeq(); /* 授信申请流水号 */
		String certType = reqSedCreditQueryBean.getCertType(); /* 证件类型 */
		String certCode = reqSedCreditQueryBean.getCertCode(); /* 证件号码 */
		String prdId = reqSedCreditQueryBean.getPrdId(); /* 产品ID */
		String apprvSts = reqSedCreditQueryBean.getApprvSts(); /* 审批状态 */
		String channelNo = reqSedCreditQueryBean.getChannelNo(); /* 渠道编号 */
		//用于接收查询结果
		List<NlsCreditInfoVO> nlsCreditInfoVOList = null;
		//查询类型不为01的情况下都需要设置身份证号和身份证类型，此处统一校验
		if (!SedCreditQueryTypeEnum.QUERY_TYPE_01.getValue().equals(qryType)) {
			// 校验证件类型，校验证件号码
			if (certType == null || "".equals(certType) || certCode == null || "".equals(certCode)) {
				throw new BizException("02、03、04、05、06查询下，证件类型、证件号码不能为空");
			}
			nlsCreditInfoVO.setCertType(certType);
			nlsCreditInfoVO.setCertCode(certCode);
		}
		//处理请求参数
		switch (SedCreditQueryTypeEnum.valueOf("QUERY_TYPE_"+qryType)) {
			case QUERY_TYPE_01:  // 01.单笔授信信息查询--授信申请流水号必输
				// 校验授信流水号
				if (lmtApplySeq == null || "".equals(lmtApplySeq)) {
					throw new BizException("01查询下，授信流水号不能为空");
				}
				nlsCreditInfoVO.setLmtApplySeq(lmtApplySeq);
				break;
			case QUERY_TYPE_02:  // 02.单客户下所有的授信申请信息-证件类型，证件号码 必输
				break;
			case QUERY_TYPE_03:  // 03.单笔客户下某个产品下所有的授信申请信息-证件类型，证件号码，产品id必输
				if ( prdId == null  || "".equals(prdId)) {
					throw new BizException("03查询下，产品ID不能为空");
				}
				nlsCreditInfoVO.setPrdCode(prdId);
				break;
			case QUERY_TYPE_04:  // 04.单笔客户下某个渠道下所有的授信申请信息-证件类型，证件号码，渠道编号必输
				if ( channelNo == null  || "".equals(channelNo)) {
					throw new BizException("04查询下，渠道编号不能为空");
				}
				nlsCreditInfoVO.setChannelNo(channelNo);
				break;
			case QUERY_TYPE_05:  // 05.单个客户下查询所有处理中、通过、拒绝的授信申请信息-证件类型、证件号码、审批状态必输。
				if ( apprvSts == null  || "".equals(apprvSts)) {
					throw new BizException("05查询下，审批状态不能为空");
				}
				break;
			case QUERY_TYPE_06: 
				if ( apprvSts == null || prdId == null  || "".equals(apprvSts)  || "".equals(prdId)) { // 06.单个客户下查询所有处理中、通过、拒绝的授信申请信息-证件类型、证件号码、产品ID、审批状态必输。
					throw new BizException("06查询下，产品Id、审批状态不能为空");
				}
				break;
			default: 
				throw new BizException("你输入的查询类型有误，请重新输入");
		}
		//01、02、03、04情况统一处理,05、06情况统一处理
		switch (SedCreditQueryTypeEnum.valueOf("QUERY_TYPE_"+qryType)) {
			case QUERY_TYPE_01:
			case QUERY_TYPE_02:
			case QUERY_TYPE_03:
			case QUERY_TYPE_04:
				nlsCreditInfoVOList = Optional.ofNullable(nlsCreditInfoService.queryAllByCondition(nlsCreditInfoVO)).orElseGet(ArrayList::new);
				break;
			//06查询的情况下需要设置产品ID
			case QUERY_TYPE_06:
				nlsCreditInfoVO.setPrdCode(prdId);
			case QUERY_TYPE_05: 
				nlsCreditInfoVOList = new ArrayList<NlsCreditInfoVO>();
				List<NlsCreditInfoVO> innerNlsCreditInfoVOList = null;
				String[] apprvStsArray = apprvSts.split(",");
				//分多个apprvSts状态多次查询
				for(String innerApprvSts : apprvStsArray ) {
					nlsCreditInfoVO.setApprvSts(innerApprvSts);
					innerNlsCreditInfoVOList = Optional.ofNullable(nlsCreditInfoService.queryAllByCondition(nlsCreditInfoVO)).orElseGet(ArrayList::new);
					//将查询到的结果都添加到返回List中
					for(NlsCreditInfoVO innerNlsCreditInfoVO : innerNlsCreditInfoVOList) {
						nlsCreditInfoVOList.add(innerNlsCreditInfoVO);
					}
				}
				break;
			default:
				//没有查询类型的情况下，防止空指针
				nlsCreditInfoVOList = new ArrayList<NlsCreditInfoVO>();
		}
		return nlsCreditInfoVOList;
	}

	public String approve30Query(ReqSedCreditQueryBean reqSedCreditQueryBean){
		NlsCreditInfoVO nlsCreditInfoVO = new NlsCreditInfoVO();
		nlsCreditInfoVO.setPrdCode(reqSedCreditQueryBean.getPrdId());
		nlsCreditInfoVO.setCertCode(reqSedCreditQueryBean.getCertCode());
		//1. 根据证件号码、证件类型、产品编号 查询授信表
		try {
			List<NlsCreditInfoVO> nlsCreditInfoVOS = nlsCreditInfoService.queryByCucCodeAndPrdId(nlsCreditInfoVO);
			if (Objects.nonNull(nlsCreditInfoVO) && nlsCreditInfoVOS.size()>0){
				//2. 根据授信号查询 授信审批表 是否存在30天内的 拒绝授信数据
				for (NlsCreditInfoVO item : nlsCreditInfoVOS){
					NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO = nlsCreditApprovalInfoService.selectByPrimaryKey(item.getLmtApplySeq());
					if (isRefuse(nlsCreditApprovalInfoVO)){
						return ZX_30DAYS_Y;
					}
				}
				return ZX_30DAYS_N;
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ZX_30DAYS_N;
	}

	private boolean isRefuse(NlsCreditApprovalInfoVO nlsCreditApprovalInfoVO){
		SimpleDateFormat fo = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String apprDate = fo.format(nlsCreditApprovalInfoVO.getApproveTime()).substring(0,10);
		if (DateUtility.ADD_DAY(apprDate,30).compareTo(TimeUtil.getCurDate().toString()) > 0 && "N".equals(nlsCreditApprovalInfoVO.getApprResult())){
			return true;
		}
		return false;
	}

	@Autowired
	@Qualifier("cusIndivService")
	private CusIndivService cusIndivService;
	@Autowired
	@Qualifier("nlsCreditInfoService")
	private NlsCreditInfoService nlsCreditInfoService;
	@Autowired
	@Qualifier("nlsProcessBizService")
	private NlsProcessBizService nlsProcessBizService;
	@Autowired
	@Qualifier("nlsCreditApprovalInfoService")
	private NlsCreditApprovalInfoService nlsCreditApprovalInfoService;
}
